package com.ifinc.common.web.frame;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Map;

/**
 * User: luotao
 * Date: 13-11-27
 * Time: 15:02
 */
@Controller
public class FrontController {
    private ConfigContext configContext;

    private HttpTransform httpTransform = new HttpTransform();

    private String baseActionPath;

    ClassManager classManager = new ClassManager();

    @Autowired
    public void setConfigContext(ConfigContext configContext) {
        this.configContext = configContext;
    }

    @Value("${baseActionPath}")
    public void setBaseActionPath(String baseActionPath) {
        this.baseActionPath = baseActionPath;
    }

    @RequestMapping("exe/{className}/{methodName}")
    @Transactional
    public String exe(HttpServletRequest request, HttpServletResponse response,
                      @PathVariable String className,
                      @PathVariable String methodName) throws Exception {
        ClassInfo classInfo = classManager.loadClassInfos(baseActionPath, className);
        ExecutorJsp executorJsp = new ExecutorJsp(classInfo,configContext);
        String result = (String) doExecute(request, response, methodName, executorJsp);
        return result;
    }

    private static final String REDIRECT_STR = "redirect:";

    @RequestMapping("redirect/{className}/{methodName}")
    @Transactional
    public void redirect(HttpServletRequest request, HttpServletResponse response,
                         @PathVariable String className,
                         @PathVariable String methodName) throws Exception {
        ClassInfo classInfo = classManager.loadClassInfos(baseActionPath, className);
        ExecutorJsp executorJsp = new ExecutorJsp(classInfo,configContext);
        String result = (String) doExecute(request, response, methodName, executorJsp);
        if (!result.startsWith(REDIRECT_STR)) {
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return;
        }
        String url = result.substring(REDIRECT_STR.length());
        response.sendRedirect(url);
    }

    @RequestMapping("json/{className}/{methodName}")
    @Transactional
    public void json(HttpServletRequest request, HttpServletResponse response,
                     @PathVariable String className,
                     @PathVariable String methodName) throws Exception {
        ClassInfo classInfo = classManager.loadClassInfos(baseActionPath, className);
        Executor executor = new Executor(classInfo,configContext);
        Object jsonObject = doExecute(request, response, methodName, executor);
        String jsonStr = JSON.toJSONString(jsonObject);
        PrintWriter out = response.getWriter();
        out.print(jsonStr);
        out.flush();
        out.close();
    }

    private Object doExecute(HttpServletRequest request, HttpServletResponse response,
                             String methodName, Executor executor) {
        Map param = httpTransform.makeParamMap(request);
        Map headerMap = httpTransform.makeHeaderParam(request);
        Map sessionMap = httpTransform.transformSession(request.getSession());
        executor.setParams(param, sessionMap, headerMap,methodName);
        Object result = executor.execute(methodName);
        httpTransform.putValueToSession(request.getSession(), executor.getSessionMap());
        httpTransform.putMap2ReqAttr(executor.getResultMap(), request);
        return result;
    }

}
